package com.siyu.core.manager.impl;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.siyu.common.email.EmailSender;
import com.siyu.common.email.MessageTemplate;
import com.siyu.common.page.Pagination;
import com.siyu.common.security.BadCredentialsException;
import com.siyu.common.security.UsernameNotFoundException;
import com.siyu.common.security.encoder.PwdEncoder;
import com.siyu.core.dao.SysUserDao;
import com.siyu.core.manager.SysUserMng;
import com.siyu.tickets.entity.SysUser;

@Service
@Transactional
public class SysUserMngImpl implements SysUserMng {

	public SysUser login(String username, String password, String ip) throws UsernameNotFoundException,
			BadCredentialsException {
		SysUser user = getByUsername(username);
		if (user == null) {
			throw new UsernameNotFoundException("username not found: " + username);
		}
		if (!pwdEncoder.isPasswordValid(user.getPassword(), password)) {
			throw new BadCredentialsException("password invalid");
		}
		if (!user.getActivation()) {
			throw new BadCredentialsException("account not activated");
		}
		updateLoginInfo(user.getId(), ip);
		return user;
	}

	public void updateLoginInfo(Integer userId, String ip) {
		Date now = new Timestamp(System.currentTimeMillis());
		SysUser user = findById(userId);
		user.setLoginCount(user.getLoginCount() + 1);
		user.setLastLoginIp(ip);
		user.setLastLoginTime(now);
	}

	public boolean usernameExist(String username) {
		return getByUsername(username) != null;
	}

	public boolean emailExist(String email) {
		return dao.countByEmail(email) > 0;
	}

	@Transactional(readOnly = true)
	public SysUser getByUsername(String username) {
		return dao.getByUsername(username);
	}

	@Transactional(readOnly = true)
	public List<SysUser> getByEmail(String email) {
		return dao.getByEmail(email);
	}

	@Transactional(readOnly = true)
	public Pagination getPage(int pageNo, int pageSize) {
		Pagination page = dao.getPage(pageNo, pageSize);
		return page;
	}

	@Transactional(readOnly = true)
	public Pagination getPage(String username, String realname, String deptname, Integer typeId, Boolean activation,
			Integer orderBy, int pageNo, int pageSize) {
		return dao.getPage(username, realname, deptname, typeId, activation, orderBy, pageNo, pageSize);
	}

	@Transactional(readOnly = true)
	public SysUser findById(Integer id) {
		SysUser entity = dao.findById(id);
		return entity;
	}

	public SysUser save(String username, String realname, String email, String password, String ip) {
		return save(username, realname, email, password, ip, true, null, null);
	}

	public SysUser save(String username, String realname, String email, String password, String ip, Boolean activation) {
		Date now = new Timestamp(System.currentTimeMillis());
		SysUser user = new SysUser();
		user.setUsername(username);
		user.setRealname(realname);
		user.setEmail(email);
		user.setPassword(pwdEncoder.encodePassword(password));
		user.setCreateTime(now);
		user.setLastLoginIp(ip);
		user.setLastLoginTime(now);
		user.setLoginCount(0);
		user.setActivation(activation);
		dao.save(user);
		return user;
	}

	public SysUser save(String username, String realname, String email, String password, String ip, Boolean activation,
			EmailSender sender, MessageTemplate msgTpl) {
		Date now = new Timestamp(System.currentTimeMillis());
		SysUser user = new SysUser();
		user.setUsername(username);
		user.setRealname(realname);
		user.setEmail(email);
		user.setPassword(pwdEncoder.encodePassword(password));
		user.setCreateTime(now);
		user.setLastLoginIp(ip);
		user.setLastLoginTime(now);
		user.setLoginCount(0);
		user.setActivation(activation);
		user.setEnable(true);
		dao.save(user);
		/*if (!activation) {
			String uuid = StringUtils.remove(UUID.randomUUID().toString(), '-');
			user.setActivationCode(uuid);
			senderEmail(username, email, uuid, sender, msgTpl);
		}*/
		return user;
	}

	/**
	 * @see SysUserMng#update(Integer, String, String)
	 */
	public SysUser update(Integer id, String password, String email) {
		SysUser user = findById(id);
		if (!StringUtils.isBlank(email)) {
			user.setEmail(email);
		} else {
			user.setEmail(null);
		}
		if (!StringUtils.isBlank(password)) {
			user.setPassword(pwdEncoder.encodePassword(password));
		}
		return user;
	}

	public boolean isPasswordValid(Integer id, String password) {
		SysUser user = findById(id);
		return pwdEncoder.isPasswordValid(user.getPassword(), password);
	}

	public SysUser deleteById(Integer id) {
		SysUser bean = dao.deleteById(id);
		return bean;
	}

	public SysUser[] deleteByIds(Integer[] ids) {
		SysUser[] beans = new SysUser[ids.length];
		for (int i = 0, len = ids.length; i < len; i++) {
			beans[i] = deleteById(ids[i]);
		}
		return beans;
	}

	public SysUser active(String username, String activationCode) {
		SysUser bean = getByUsername(username);
		bean.setActivation(true);
		bean.setActivationCode(null);
		return bean;
	}

	public SysUser activeLogin(SysUser user, String ip) {
		updateLoginSuccess(user.getId(), ip);
		return user;
	}

	public void updateLoginSuccess(Integer userId, String ip) {
		SysUser user = findById(userId);
		Date now = new Timestamp(System.currentTimeMillis());
		user.setLoginCount(user.getLoginCount() + 1);
		user.setLastLoginIp(ip);
		user.setLastLoginTime(now);
	}

	@Autowired
	private PwdEncoder pwdEncoder;
	@Autowired
	private SysUserDao dao;

}